#include <ctype.h> 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "urlencode.h"

int UrlEncode(IN char * pcBufferIn,IN int iLenIn,OUT char * pcBufferOut,IN OUT int &iLenOut)
{
	int i,iResult,iRet=-1;
	char cTempBuf[10];
	char *pcWrite,*pcRead;
	char cHexAry[] = "0123456789ABCDEF";  
	unsigned char ucCurrChar;

	if(pcBufferIn==NULL||pcBufferOut==NULL||iLenIn<=0||iLenOut<=0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_INVALIDARGS);

	pcWrite=pcBufferOut;
	for (i = 0;i<iLenIn&&pcWrite<pcBufferOut+iLenOut; i++)
	{	
		ucCurrChar = pcBufferIn[i];  
		if (isascii(ucCurrChar))  
		{  
			if (ucCurrChar == ' ')  
			{  
				if(i+2<iLenOut)
				{
					pcWrite[0]='%';
					pcWrite[1]='2';
					pcWrite[2]='0';
					pcWrite+=3;
				}
				else
				{
					iRet=-1;
					goto _Exit;
				}
			}  
			else 
			{
				*pcWrite = ucCurrChar;  
				pcWrite++;
			}
		}  
		else 
		{  
			if(i+2<iLenOut)
			{
				pcWrite[0]='%';
				pcWrite[1]=cHexAry[(ucCurrChar&0xf0)>>4];
				pcWrite[2]=cHexAry[(ucCurrChar&0x0f)];
				pcWrite+=3;
			}
			else
			{
				iRet=-1;
				goto _Exit;
			}
		}  
	}

	if(i==iLenIn) iRet=0;
	else iRet=-1;

	if(pcWrite<pcBufferOut+iLenOut) *pcWrite=0;
	else iRet=-1;
	
	iLenOut=pcWrite-pcBufferOut;

_Exit:
	return iRet;
}

int UrlDecode(IN char * pcBufferIn,IN int iLenIn,OUT char * pcBufferOut,IN OUT int &iLenOut)
{
	int i,iResult,iRet=-1;
	char cTempBuf[10];
	char *pcWrite,*pcRead;

	if(pcBufferIn==NULL||pcBufferOut==NULL||iLenIn<=0||iLenOut<=0) SET_RET_AND_GOTO_EXIT(COMMON_ERR_INVALIDARGS);

	pcWrite=pcBufferOut;
	for (i = 0; i<iLenIn&&pcWrite<pcBufferOut+iLenOut; i++)
	{
		switch (pcBufferIn[i])
        {
        case '+':
			*pcWrite = ' ';
            break;
        case '%':
			if(i+2<iLenIn)
			{
				if (isxdigit(pcBufferIn[i + 1]) && isxdigit(pcBufferIn[i + 2]))
				{
					cTempBuf[0]=pcBufferIn[i + 1];
					cTempBuf[1]=pcBufferIn[i + 2];
					cTempBuf[2]=0;
					iResult = strtol(cTempBuf, NULL, 16);
					/*//字母和数字[0-9a-zA-Z]、一些特殊符号[$-_.+!*'(),] 、以及某些保留字[$&+,/:;=?@]
					//可以不经过编码直接用于URL
					if (!((iResult >= 48 && iResult <= 57) || //0-9
						(iResult >=97 && iResult <= 122) ||   //a-z
						(iResult >=65 && iResult <= 90) ||    //A-Z
						//一些特殊符号及保留字[$-_.+!*'(),]  [$&+,/:;=?@]
						iResult == 0x21 || iResult == 0x24 || iResult == 0x26 || iResult == 0x27 || iResult == 0x28 || iResult == 0x29
						|| iResult == 0x2a || iResult == 0x2b|| iResult == 0x2c || iResult == 0x2d || iResult == 0x2e || iResult == 0x2f
						|| iResult == 0x3A || iResult == 0x3B|| iResult == 0x3D || iResult == 0x3f || iResult == 0x40 || iResult == 0x5f
						))
					{
						*pcWrite = (char)iResult;
						i += 2;
					}
					else *pcWrite = '%';*/
					*pcWrite = (char)iResult;
					i += 2;
				}else *pcWrite = '%';
			}
			else *pcWrite = '%';
            break;
        default:
            *pcWrite = pcBufferIn[i];
            break;
        }
		pcWrite++;
	}
	if(i==iLenIn) iRet=0;
	else iRet=-1;

	if(pcWrite<pcBufferOut+iLenOut) *pcWrite=0;
	else iRet=-1;
	
	iLenOut=pcWrite-pcBufferOut;

_Exit:
	return iRet;
}
